// // Copyright (c) 2009 All Right Reserved // // vl // // 2009-01-01 // Contains ... using System; using System.Linq; using LargoCommon.Abstract; using LargoCommon.Localization; using LargoCommon.Music; namespace LargoCommon.Composer { /// /// Body Composer. /// public class BodyComposer { /// /// Gets or sets the body. /// /// /// The body. /// public MusicalBody Body { get; set; } /// /// Composes the music. /// /// The given body. public void ComposeMusic(MusicalBody givenBody) { this.Body = givenBody; ElementComposer elementComposer = new ElementComposer(); ProcessLogger.Singleton.SendLogEvent(null, LocalizedMusic.String("Preparing rhythm..."), 0); foreach (var bar in this.Body.Bars) { bar.FillTracksWithRhythm(); bar.MakeHarmonicClusters(); } //// Prepare Planned Tones, correct melodic type. //// int percentage; ProcessLogger.Singleton.SendLogEvent(null, LocalizedMusic.String("Preparing planned tones..."), 0); foreach (var bar in this.Body.Bars) { //// percentage = (100 * bar.BarNumber) / this.Bars.Count; bar.PreparePlannedTones(); //// Correct melodic type - eliminate parallel individualized melodic voices if (this.Body.Context.Settings.Rules.IndividualizeMelodicVoices) { bar.EliminateParallelMelodies(); } } var elements = (from elem in this.Body.AllElements where elem.Status != null && elem.Line.Purpose == LinePurpose.Composed //// 2019/12 //// && elem.Status.LocalPurpose == LinePurpose.Composed && elem.Status.IsMelodicalNature select elem).ToList(); foreach (var elem in elements) { elem.IsFinished = false; } ProcessLogger.Singleton.SendLogEvent(null, LocalizedMusic.String("Composing lines..."), 0); float cntElems; int numElem; if (!this.Body.Context.Settings.Rules.IndividualizeMelodicVoices) { var melodicOriginals = (from elem in elements where elem.Status.IsMelodicOriginal orderby elem.Status.Priority, elem.Bar.BarNumber select elem).ToList(); cntElems = melodicOriginals.Count; numElem = 0; foreach (var elem in melodicOriginals) { numElem++; int percent = (int)Math.Floor(100 * numElem / cntElems); if (percent % 2 == 0) { //// percentageChange ProcessLogger.Singleton.SendLogEvent(elem.ToProgressString(), LocalizedMusic.String("Composing lines..."), percent); } elementComposer.ComposeMelody(elem); elem.IsFinished = true; } //// Parallel melodic motives (variant) - if are the same, then here are set the same tones //// substituted = element.AppendDoubledMelodicTones(); var dependentElements = (from elem in elements where !elem.IsFinished && elem.Status.OriginalMelodicPoint.IsDefined //// !?! && elem.OriginalMelodicPoint.IsComposed orderby elem.Status.Priority, elem.Bar.BarNumber select elem).ToList(); foreach (var elem in dependentElements) { var point = elem.Status.OriginalMelodicPoint; var origin = this.Body.GetElement(point); if (origin != null) { elem.Tones = origin.Tones.Clone(false); elem.IsFinished = true; } } } ProcessLogger.Singleton.SendLogEvent(null, LocalizedMusic.String("Finishing lines..."), 0); var restElements = (from elem in elements where !elem.IsFinished orderby elem.Status.Priority, elem.Bar.BarNumber select elem).ToList(); cntElems = restElements.Count; numElem = 0; foreach (var elem in restElements) { numElem++; int percent = (int)Math.Floor(100 * numElem / cntElems); if (percent % 2 == 0) { //// percentageChange ProcessLogger.Singleton.SendLogEvent(elem.ToProgressString(), LocalizedMusic.String("Finishing lines..."), percent); } elementComposer.ComposeMelody(elem); elem.IsFinished = true; } //// Complete tone instruments from current element statuses. ProcessLogger.Singleton.SendLogEvent(null, LocalizedMusic.String("Orchestration..."), 0); foreach (var bar in this.Body.Bars) { bar.SendStatusToTones(); } } } }